package cLog

import (
	"context"
	"strings"

	"github.com/sirupsen/logrus"

	"gitee.com/csingo/cHelper"

	"gitee.com/csingo/cCommon"
)

var logger *logrus.Logger

func load() {
	build_path = cHelper.GetBuildPath()

	logger = logrus.New()

	logger.SetOutput(NewEmptyWriter())
	logger.SetLevel(log_config.Level)

	for _, driver := range log_config.Drivers {
		var hook logrus.Hook
		switch driver {
		default:
			fallthrough
		case LOG_DRIVER_STDOUT:
			hook = log_config.Clients.Stdout
		case LOG_DRIVER_FILE:
			hook = log_config.Clients.File
		case LOG_DRIVER_LOKI:
			log_config.Clients.Loki.Consume()
			hook = log_config.Clients.Loki
		}
		logger.AddHook(hook)
	}
}

func WithContext(ctx context.Context, params map[string]any, opts ...[]Option) *logrus.Entry {
	if logger == nil {
		load()
	}

	var traceid string
	if ctx != nil {
		v := ctx.Value(cCommon.XIndex_TraceId)
		if v != nil {
			traceid = v.(string)
		}
	}

	var options []Option
	for _, opt := range opts {
		options = append(options, opt...)
	}

	skip := caller_skip
	includes := []string{build_path}
	excludes := []string{}

	for _, opt := range options {
		switch opt.(type) {
		case CallerSkip:
			skip = opt.Value().(int)
		case IncludePaths:
			includes = opt.Value().([]string)
		case ExcludePaths:
			excludes = opt.Value().([]string)
		}
	}

	reporter := cHelper.GetCallerFileAndLine(skip, includes, excludes)

	fields := map[string]any{
		LOG_FIELD_PARAMS:   params,
		LOG_FIELD_REPORTER: reporter,

		strings.ToLower(cCommon.XIndex_TraceId): traceid,
	}
	for k, v := range log_config.WithFields {
		fields[k] = v
	}

	for _, item := range log_config.Excludes {
		delete(fields, item)
	}

	return logger.WithContext(ctx).WithFields(fields)
}

func Level(level logrus.Level) {
	logger.SetLevel(level)
}
